package minicat.utils;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import minicat.catalina.components.Context;

import java.io.FileInputStream;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 从本地加载文件
 */
public class DiskClassLoader extends ClassLoader {

    private final Map<String, Class<?>> contextClasses = new ConcurrentHashMap<>(10);

    public Class<?> findClass(Context context, String className, String absolutePath) {

        if (contextClasses.containsKey(className)) {
            return contextClasses.get(className);
        }

        absolutePath = StrUtil.replace(absolutePath, "\\","/");
        byte[] fileBytes = loadBytes(absolutePath);
        Class<?> clazz = defineClass(className, fileBytes, 0, fileBytes.length);
        if (Objects.isNull(clazz)) {
            try {
                clazz = super.findClass(className);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        contextClasses.put(context.getDocBase(), clazz);
        return clazz;
    }

    private byte[] loadBytes(String absolutePath) {
        try (FileInputStream fis = new FileInputStream(absolutePath)) {
            int length = fis.available();
            byte[] bytes = new byte[length];
            fis.read(bytes);
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException("CLASSLOADER ERROR:"+ ExceptionUtil.stacktraceToString(e));
        }
    }

}